package com.uw.uwregistry.service;

import com.uw.uwregistry.constant.UWRegistryConstant;
import com.uw.uwregistry.meta.InstanceMeta;
import com.uw.uwregistry.meta.ServiceMeta;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

@Slf4j
public class UWRegistryService implements RegistryService {

    private final static AtomicLong VERSION = new AtomicLong(0);


    @Override
    public InstanceMeta register(String serviceSign, InstanceMeta instanceMeta) {
        List<InstanceMeta> instanceMetas = fetchAll(serviceSign);
        if (!CollectionUtils.isEmpty(instanceMetas)) {
            if (instanceMetas.contains(instanceMeta)) {
                log.info(" ==> 服务已存在：{}", instanceMeta);
                instanceMeta.setStatus(UWRegistryConstant.Instance_up_status);
                return instanceMeta;
            }
        }
        log.info(" ==> 注册服务：{}", instanceMeta);
        RegistryContainer.addInstance(serviceSign, instanceMeta);
        instanceMeta.setStatus(UWRegistryConstant.Instance_up_status);

        heartbeat(instanceMeta, serviceSign);
        RegistryContainer.putVersionMap(serviceSign, VERSION.incrementAndGet());
        RegistryContainer.updateContainerVersion(VERSION.incrementAndGet());
        return instanceMeta;
    }

    @Override
    public InstanceMeta unregister(String serviceSign, InstanceMeta instanceMeta) {
        List<InstanceMeta> instanceMetas = fetchAll(serviceSign);
        if (CollectionUtils.isEmpty(instanceMetas)) {
            log.info(" ==> 服务不存在：{}", serviceSign);
            return null;
        }

        log.info(" ==> 注销服务：{}", instanceMeta);
        instanceMetas.removeIf(e -> e.equals(instanceMeta));
        instanceMeta.setStatus(UWRegistryConstant.Instance_down_status);

        heartbeat(instanceMeta, serviceSign);
        RegistryContainer.putVersionMap(serviceSign, VERSION.incrementAndGet());
        RegistryContainer.updateContainerVersion(VERSION.incrementAndGet());
        return instanceMeta;
    }

    @Override
    public long heartbeat(InstanceMeta instanceMeta, String... serviceSigns) {
        long now = System.currentTimeMillis();
        for (String serviceSign : serviceSigns) {
            RegistryContainer.putHeartbeatMao(serviceSign + "@" + instanceMeta.toUrl(), now);
        }
        return now;
    }

    @Override
    public Map<String, Long> version(String... serviceSigns) {
        return Arrays.stream(serviceSigns).collect(Collectors.toMap(k -> k, RegistryContainer.versionMap()::get, (v1, v2) -> v2));
    }


    @Override
    public List<InstanceMeta> fetchAll(String serviceSign) {
        return RegistryContainer.getIntanceList(serviceSign);
    }

    @Override
    public InstanceMeta register(ServiceMeta serviceMeta, InstanceMeta instanceMeta) {
        return register(serviceMeta.serviceSign(), instanceMeta);
    }

    @Override
    public InstanceMeta unregister(ServiceMeta serviceMeta, InstanceMeta instanceMeta) {
        return unregister(serviceMeta.serviceSign(), instanceMeta);
    }

    @Override
    public List<InstanceMeta> fetchAll(ServiceMeta serviceMeta) {
        return fetchAll(serviceMeta.serviceSign());
    }

}
